package com.cyt.sys.extend.netty;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * netty长连接handler实现
 *
 * @author taocongcong
 * @create 2019-03-12 14:47
 */
public class WebSocketServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    /**
     * 不同组怎么处理
     */
    public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * key是组名，value是组内成员
     */
    public static Map<String, ChannelGroup> channelGroupMap = new HashMap<>();

    /**
     * key用户id
     */
    public static Map<String, Channel> userChannelMap = new HashMap<>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        System.out.println("收到消息: " + msg.text());
        ctx.channel().writeAndFlush(new TextWebSocketFrame("服务端已收到，请确认！"));
        // JSONObject object = JSON.parseObject(msg.text());
    }

    /**
     * 连接建立时
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("handlerAddred " + ctx.channel().id().asLongText());
        // 获取连接的channel
        Channel incomming = ctx.channel();
        // 通知所有已经连接到服务器的客户端，有一个新的通道加入
        /*for (Channel channel : channels) {
            System.out.print("[SERVER]-"+incomming.remoteAddress()+"加入\n");
        }*/
        channels.add(ctx.channel());

        //userChannelMap.put(String.valueOf(userId), incomming);
    }

    /**
     * 连接关闭时
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("handlerRemoved " + ctx.channel().id().asLongText());
        //获取连接的channel
        Channel incomming = ctx.channel();
        /*for (Channel channel : channels) {
            channel.writeAndFlush("[SERVER]-"+incomming.remoteAddress()+"离开\n");
        }*/
        //从服务端的channelGroup中移除当前离开的客户端
        channels.remove(ctx.channel());
        //userChannelMap.remove(String.valueOf(userId));
        // 关闭其他
        String userId = "";
        if (userChannelMap != null && userChannelMap.size() > 0) {
            Iterator<Map.Entry<String, Channel>> it = userChannelMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, Channel> entry = it.next();
                if (entry.getValue() == ctx.channel()) {
                    // 删除元素
                    it.remove();
                    userId = entry.getKey();
                }
            }
        }
        if (channelGroupMap != null && channelGroupMap.size() > 0) {
            for (Map.Entry<String, ChannelGroup> entry : channelGroupMap.entrySet()) {
                ChannelGroup value = entry.getValue();
                value.remove(ctx.channel());
            }
        }
    }

    /**
     * 异常发生时
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("异常发生");
        ctx.close();
    }
}
